#ifndef SIMPLEFACTORY_34056396_H
#define SIMPLEFACTORY_34056396_H
//////////////////////////////////////////////////////////////////////
/**
 *  Simple factory implementation.
 *  \file       SimpleFactory.h
 *  \author     Pierre Renaux
 *  \date       December 27, 2006
 */
//////////////////////////////////////////////////////////////////////

#include <map>

template <typename T, typename TPA = void*, typename TPB = void*>
struct SimpleFactory
{
	struct sCompareString {
		bool operator () (const std::string& a, const std::string& b) const {
			return strcmp(a.c_str(),b.c_str()) < 0;
		}
	};
	typedef T* (__stdcall *tpfnCreate)(TPA apA, TPB apB);	
	typedef std::map<std::string,tpfnCreate,sCompareString>			tContainer;	// use a map, the names are automatically sorted
	typedef typename tContainer::const_iterator						tIterator;

	static tContainer& __stdcall Container() {
		static tContainer _container;
		return _container;
	}

	static size_t __stdcall Size() {
		return Container().size();
	}
	static tIterator __stdcall Begin() {
		return Container().begin();
	}
	static tIterator __stdcall End() {
		return Container().end();
	}
	static const char* __stdcall GetNameAt(unsigned int anIndex) {
		unsigned int c = 0;
		for(tIterator it = Container().begin(); it != Container().end(); ++it) {
			if (c++ == anIndex)
				return it->first.c_str();
		}
		return "";
	}
	static tpfnCreate __stdcall GetCreateAt(unsigned int anIndex) {
		unsigned int c = 0;
		for(tIterator it = Container().begin(); it != Container().end(); ++it) {
			if (c++ == anIndex)
				return it->second;
		}
		return NULL;
	}
	static tIterator __stdcall FindName(const char* aaszName) {
		return Container().find(aaszName);
	}
	static tIterator __stdcall FindCreate(tpfnCreate apfnCreate) {
		aglLoopit(Container(),tIterator) {
			if (it->second == apfnCreate)
				return it;
		}
		return End();
	}
	static void Register(const char* aaszName, tpfnCreate apfnCreate) {
		Container()[aaszName] = apfnCreate;
	}
	static T* Create(const char* aaszName, TPA apA, TPB apB) {
		tIterator it = FindName(aaszName);
		if (it == End()) return NULL;
		return it->second(apA,apB);
	}

	struct sRegister {
		sRegister(const char* aaszName, tpfnCreate apfnCreate) {
			Register(aaszName,apfnCreate);
		}
	};

private:	
};

/// EOF //////////////////////////////////////////////////////////////////////////////////////
#endif // SIMPLEFACTORY_34056396_H
